package com.example.studentalarm.widget;


import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;

import com.example.studentalarm.utils.ScreenUtils;
import com.example.studentalarm.widget.head.DragHeaderImpl;
import com.example.studentalarm.widget.head.IPhoneHeader;


/**
 * @author ZHQ
 * @create 2019/3/22
 * @Describe
 */
public class AppleRefreshView extends LinearLayout {
    /**
     * 下拉刷新状态
     */
    public static final int REFRESH_BY_PULLDOWN = 0;

    /**
     * 松开刷新状态
     */
    public static final int REFRESH_BY_RELEASE = 1;
    /**
     * 正在刷新状态
     */
    public static final int REFRESHING = 2;
    /**
     * 刷新成功状态
     */
    public static final int REFRESHING_SUCCESS = 3;
    /**
     * 刷新失败状态
     */
    public static final int REFRESHING_FAILD = 4;
    private View mHeaderView;
    private int refreshTargetTop;
    private ObjectAnimator anim;
    private RefreshListener refreshListener;
    private int lastY;
    private int mHeaderViewHeight;
    private boolean isRefreshEnabled = true;// 是否可刷新标记

    private int scaleTouchSlop;
    /**
     * layout inflater
     */
    private LayoutInflater mInflater;
    int refreshState = REFRESH_BY_PULLDOWN;
    private Context mContext;

    public AppleRefreshView(Context context) {
        this(context, null);
    }

    public AppleRefreshView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        scaleTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        init();
    }

    @SuppressLint("ObjectAnimatorBinding")
    private void init() {
        setOrientation(VERTICAL);
        mInflater = LayoutInflater.from(getContext());
        addHeader(new IPhoneHeader(mContext));//BikeGoodsHeader  new IPhoneHeader(mContext)
    }

    private void initLayout() {
        //LogUtil.e("headerView height:"+mHeaderView.getHeight());
        // header layout
        measureView(mHeaderView);//测量头部布局的高度
        mHeaderViewHeight = mHeaderView.getMeasuredHeight();
        refreshTargetTop = -ScreenUtils.dpToPx(getResources(), 60);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, -refreshTargetTop);    // 设置topMargin的值为负的header View高度,即将其隐藏在最上方
        lp.topMargin = refreshTargetTop;
        lp.gravity = Gravity.CENTER;
        addView(mHeaderView, 0, lp);
        anim = ObjectAnimator.ofFloat(mHeaderView, "alpha", 0.0f, 1.0f);
    }

    private DragHeaderImpl headerHeader;


    public void addHeader(DragHeaderImpl headerListener) {
        this.headerHeader = headerListener;
        mHeaderView = headerListener.getView(mInflater, this);
        initLayout();
    }


    /***
     *
     * @param child
     */
    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        }

        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }


    private Handler handler = new Handler();

    private class ThreadRefresh implements Runnable {

        @Override
        public void run() {
            refreshListener.onRefresh();
        }
    }



    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int y = (int) event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //记录下y坐标
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                //y移动坐标
                int m = y - lastY;
                doMovement(m);
                //记录下此刻y坐标
                this.lastY = y;
                break;
            case MotionEvent.ACTION_UP:
                fling();
                break;
        }
        return true;
    }

    /**
     * up事件处理
     */
    private void fling() {
        LayoutParams lp = (LayoutParams) mHeaderView.getLayoutParams();
        if (lp.topMargin > 0) {//拉到了触发可刷新事件
            refresh();
        } else {//收回
            animRefreshView(lp.topMargin, refreshTargetTop, 300);
        }
    }

    private void refresh() {
        LayoutParams lp = (LayoutParams) this.mHeaderView.getLayoutParams();
        int i = lp.topMargin;
        animRefreshView(i, 0, 200);
        refreshing();
        if (refreshListener != null) {
            setRefreshState(REFRESHING);
            handler.postDelayed(new ThreadRefresh(), 500);
        }
    }

    /**
     * 下拉move事件处理
     *
     * @param moveY
     */
    private void doMovement(int moveY) {
        if (anim.isRunning() || refreshState == REFRESHING) {
            return;
        }
        LayoutParams lp = (LayoutParams) mHeaderView.getLayoutParams();
        float f1 = lp.topMargin;
        int i = (int) (f1 + moveY * 0.4F);
        if (i >= refreshTargetTop) {//如果下拉大于-60dp的高度,动态刷新子视图
            lp.topMargin = i;
            mHeaderView.setLayoutParams(lp);
            mHeaderView.invalidate();
            invalidate();
        }
        if (moveY < mHeaderViewHeight) {//下拉距离不能超过临界点
            headerHeader.onDropAnim(this, moveY, mHeaderViewHeight);
        }
        if (lp.topMargin > 0) {//松开刷新状态
            if (refreshState != REFRESH_BY_RELEASE) {
                pullUpToRefresh();
            }
        } else {//下拉刷新状态
            if (refreshState != REFRESH_BY_PULLDOWN) {
                pullDownToRefresh();
            }
        }

    }

    /**
     * 设置是否可以刷新
     *
     * @param b
     */
    public void setRefreshEnabled(boolean b) {
        this.isRefreshEnabled = b;
    }

    /**
     * 设置刷新回调
     *
     * @param listener
     */
    public void setRefreshListener(RefreshListener listener) {
        this.refreshListener = listener;
    }

    /**
     * 获取当前刷新状态
     *
     * @return
     */
    public int getRefreshState() {
        return refreshState;
    }

    /**
     * 设置当前刷新状态
     *
     * @param refreshState
     */
    public void setRefreshState(int refreshState) {
        this.refreshState = refreshState;
    }


    /**
     * 结束刷新事件
     */
    public void finishRefresh(boolean isOK) {
        LayoutParams lp = (LayoutParams) this.mHeaderView.getLayoutParams();
        final int i = lp.topMargin;
        if (isOK) {
            refreshOK();
        } else {
            refreshFailed();
        }
        if (!anim.isRunning() && refreshState != REFRESHING) {
            new Handler().postDelayed(new Runnable() {
                public void run() {
                    animRefreshView(i, refreshTargetTop, 500);
                }
            }, 300);
        }
    }

    private float lastX;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        if (!isRefreshEnabled) {
            return false;
        }
        int action = e.getAction();
        int y = (int) e.getRawY();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                lastY = y;
                lastX = e.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                boolean isScroll = canScroll();
                if (isScroll) {
                    float moveX = e.getX();
                    float instanceX = Math.abs(moveX - lastX);
                    // 容差值大概是24，再加上60
                    if (instanceX > scaleTouchSlop + 60) {
                        return false;
                    }
                    if (y > lastY) {
                        return true;
                    }
                }
                //记录下此刻y坐标
                this.lastY = y;
                break;
        }
        return false;
    }

    private boolean canScroll() {
        View childView;
        if (getChildCount() > 1) {
            childView = this.getChildAt(1);
            if (childView instanceof ListView) {
                int top = ((ListView) childView).getChildAt(0).getTop();
                int pad = ((ListView) childView).getListPaddingTop();
                if ((Math.abs(top - pad)) < 3 &&
                        ((ListView) childView).getFirstVisiblePosition() == 0) {
                    return true;
                } else {
                    return false;
                }
            } else if (childView instanceof ScrollView) {
                if (((ScrollView) childView).getScrollY() == 0) {
                    return true;
                } else {
                    return false;
                }
            }  else if (childView instanceof WebView) {
                if (((WebView) childView).getScrollY() == 0) {
                    return true;
                } else {
                    return false;
                }
            } else if (childView instanceof GridView) {
                int top = ((GridView) childView).getChildAt(0).getTop();
                int pad = ((GridView) childView).getListPaddingTop();
                if ((Math.abs(top - pad)) < 3 &&
                        ((GridView) childView).getFirstVisiblePosition() == 0) {
                    return true;
                } else {
                    return false;
                }
            } else if (childView instanceof RecyclerView) {
                if (((RecyclerView) childView).computeVerticalScrollOffset() == 0) {
                    return true;
                } else {
                    return false;
                }
//                RecyclerView.LayoutManager manager = ((RecyclerView) childView).getLayoutManager();
//                int top = 0;
//                if (manager instanceof LinearLayoutManager) {
//                    top = ((LinearLayoutManager) manager).findFirstVisibleItemPosition();
//                } else if (manager instanceof StaggeredGridLayoutManager) {
//                    top = ((StaggeredGridLayoutManager) manager).findFirstVisibleItemPositions(null)[0];
//                }
//                if (((RecyclerView) childView).getChildAt(0) != null) {
//                    //判断子item是否marginTop有距离，子item布局如果marginTop距离的话，返回false并且下拉刷新无效
//                    if (((RecyclerView) childView).getChildAt(0).getY() == 0 && top == 0) {
//                        return true;
//                    } else {
//                        return false;
//                    }
//                }
            }

        }
        return false;
    }

    /**
     * 从开始位置滑动到结束位置
     *
     * @param startHeight
     * @param endHeight
     */
    public void animRefreshView(final int startHeight, final int endHeight, int duration) {
        anim.start();
        anim.setDuration(duration);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float cVal = (Float) animation.getAnimatedValue();
                LayoutParams lp = (LayoutParams) mHeaderView.getLayoutParams();
                int k = startHeight + (int) (cVal * (endHeight - startHeight));
                lp.topMargin = k;
                mHeaderView.setLayoutParams(lp);
                mHeaderView.invalidate();
                invalidate();
            }
        });

    }

    /**
     * 刷新监听接口
     */
    public interface RefreshListener {
        void onRefresh();
    }

    /**
     * 下拉刷新状态
     */
    public void pullDownToRefresh() {
        setRefreshState(REFRESH_BY_PULLDOWN);
        headerHeader.onLimitDes(this, true);
    }

    /**
     * 松开刷新状态
     */
    public void pullUpToRefresh() {
        setRefreshState(REFRESH_BY_RELEASE);
        headerHeader.onLimitDes(this, false);
    }

    /**
     * 正在刷新状态
     */
    public void refreshing() {
        setRefreshState(REFRESHING);
        headerHeader.onStartAnim();
    }

    /**
     * 刷新成功状态
     */
    public void refreshOK() {
        setRefreshState(REFRESHING_SUCCESS);
        headerHeader.onFinishAnim(true);
    }

    /**
     * 刷新失败状态
     */
    public void refreshFailed() {
        setRefreshState(REFRESHING_FAILD);
        headerHeader.onFinishAnim(false);
    }

    public void cleanCache() {
        handler.removeCallbacksAndMessages(null);
    }


}
